博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RBAC 基于角色的权限控制
阅读量:6673 次
发布时间:2019-06-25

本文共 23885 字,大约阅读时间需要 79 分钟。

RBAC 基于角色的权限控制

​ (Role-Based Access Control)

  1. 为什么要有权限:

    区分用户的 功能

    在web开发中 url代表权限

表结构:

from django.db import modelsclass Permission(models.Model):    url = models.CharField(max_length=32, verbose_name='权限')    title = models.CharField(max_length=32, verbose_name='标题')    class Meta:        verbose_name_plural = '权限'        verbose_name = '权限'    def __str__(self):        return self.titleclass Role(models.Model):    """    角色表    """    name = models.CharField(max_length=32, verbose_name='名称')    permissions = models.ManyToManyField('Permission', verbose_name='角色拥有的权限', blank=True)    def __str__(self):        return self.nameclass User(models.Model):    """    用户表    """    name = models.CharField(max_length=32, verbose_name='名称')    password = models.CharField(max_length=32, verbose_name='密码')    roles = models.ManyToManyField('Role', verbose_name='用户拥有的角色', blank=True)    def __str__(self):        return self.name

流程

  1. 录入权限信息到数据库

  2. 登录成功后保存用户的权限到session中

    def login(request):    if request.method == 'POST':        user = request.POST.get('user')        pwd = request.POST.get('pwd')        obj = models.User.objects.filter(name=user, password=pwd).first()        if not obj:            return render(request, 'login.html', {'error_msg': '用户名或密码错误'})        # 登陆成果  保存权限的信息        ret = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__url',                                                                            'permissions__title').distinct()        # 保存权限信息        request.session[settings.PERMISSION_SESSION_KEY] = list(ret)        return redirect(reverse('customer_list'))    return render(request, 'login.html')

    在setting 配置中 配置

    # ################################ 权限的配置 ################################# 权限的keyPERMISSION_SESSION_KEY = 'permissions'# 菜单的keyPERMISSION_MENU_KEY = 'menus'WHITE_LIST = [    r'^/login/$',    r'^/reg/$',    r'^/admin/.*',]
  3. 中间件中对权限进行检验(白名单)

    class RbacMiddleware(MiddlewareMixin):    def process_request(self, request):        # 1. 获取当前访问的URL        url = request.path_info        # 白名单           for i in settings.WHITE_LIST:            if re.match(i, url):                return        # 2. 获取当前用户的权限信息   无权限的 跳转 login        permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)         if not permission_list:            return redirect(reverse('login'))        # 3. 权限的校验        for i in permission_list:            if re.match(r"^{}$".format(i['url']), url):                return        # 拒绝访问        return HttpResponse('没有访问权限')

一级菜单

动态生成一级菜单

  • 表结构

    • 权限表 角色表 用户表
    • 权限和角色的多对多关系表 用户和角色的多对多关系表
    from django.db import modelsclass Permission(models.Model):    """    权限表    可做菜单的权限    is_menu=True    不可做菜单的权限  is_menu=False    """    url = models.CharField(max_length=32, verbose_name='权限')    title = models.CharField(max_length=32, verbose_name='标题')    is_menu = models.BooleanField(default=False, verbose_name='是否是菜单')    icon = models.CharField(max_length=64, null=True, blank=True, verbose_name='图标')    class Meta:        verbose_name_plural = '权限'        verbose_name = '权限'    def __str__(self):        return self.titleclass Role(models.Model):    """    角色表    """    name = models.CharField(max_length=32, verbose_name='名称')    permissions = models.ManyToManyField('Permission', verbose_name='角色拥有的权限', blank=True)    def __str__(self):        return self.nameclass User(models.Model):    """    用户表    """    name = models.CharField(max_length=32, verbose_name='名称')    password = models.CharField(max_length=32, verbose_name='密码')    roles = models.ManyToManyField('Role', verbose_name='用户拥有的角色', blank=True)    def __str__(self):        return self.name
  • 流程:

    1. 保存菜单的信息到 session 中
    # 在 rbac app中 定义 一个文件 处理 信息的 录入def init_permisson(request, obj):    """    权限信息的初识化    保存权限和菜单的信息    :param request:    :param obj:    :return:    """    ret = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__url',                                                                        'permissions__title',                                                                        'permissions__is_menu',                                                                        'permissions__icon',                                                                        ).distinct()    # 存放权限信息    permission_list = []    # 存放菜单信息    menu_list = []    for item in ret:        # 将所有的权限信息添加到permission_list        permission_list.append({'url': item['permissions__url']})        # 把是菜单的权限信息放入到menu_list        if item.get('permissions__is_menu'):            menu_list.append({'url': item['permissions__url'], 'title': item['permissions__title'],                              'icon': item['permissions__icon']})    # 保存权限信息    request.session[settings.PERMISSION_SESSION_KEY] = permission_list    # 保存菜单信息    request.session[settings.PERMISSION_MENU_KEY] = menu_list
    1. 定义 菜单的 heml 代码块 使用 inclusion_tag

      html 代码 menu.html

      {#
      #} {# 客户管理#} {#
      #} {# 账单管理#} {% for item in menu_list %}
      {
      { item.title }}
      {% endfor %}

      inclusion_tag

      from django import templatefrom django.conf import settingsimport reregister = template.Library()@register.inclusion_tag('rbac/menu.html')def menu(request):    menu_list = request.session.get(settings.PERMISSION_MENU_KEY)    for item in menu_list:        if re.match("^{}$".format(item['url']), request.path_info):            item['class'] = 'active'            break    return {'menu_list': menu_list}
    2. 定义 代码块的css 样式 menu.css

      .static-menu .icon-wrap {    width: 20px;    display: inline-block;    text-align: center;}.static-menu a {    text-decoration: none;    padding: 8px 15px;    border-bottom: 1px solid #ccc;    color: #333;    display: block;    background: #efefef;    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));    background: -ms-linear-gradient(bottom, #efefef, #fafafa);    background: -moz-linear-gradient(center bottom, #efefef 0%, #fafafa 100%);    background: -o-linear-gradient(bottom, #efefef, #fafafa);    filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";    box-shadow: inset 0px 1px 1px white;}.static-menu a:hover {    color: #2F72AB;    border-left: 2px solid #2F72AB;}.static-menu a.active {    color: #2F72AB;    border-left: 2px solid #2F72AB;}
    3. 在 母版中 导入 css 样式 以及使用 inclusion_tag 返回菜单列表

      {% load rbac %} {% menu request %}

二级菜单

动态生成二级菜单

表结构:

from django.db import models# Create your models here.class Menu(models.Model):    ''' 一级菜单 '''    title = models.CharField(max_length=32)    icon = models.CharField(max_length=64, null=True, blank=True, verbose_name='图标')    def __str__(self):        return self.titleclass Permission(models.Model):    '''    权限表    可以做二级菜单的权限   menu 关联 菜单表    不可以做菜单的权限   menu=null    '''    url = models.CharField(max_length=32, verbose_name='路径')    title = models.CharField(max_length=32, verbose_name='描述')    menu = models.ForeignKey('Menu', null=True, blank=True)    def __str__(self):        return self.titleclass Role(models.Model):    '''    角色表 部门    '''    name = models.CharField(max_length=32, verbose_name='角色')    permissions = models.ManyToManyField('Permission', verbose_name='角色拥有的权限', blank=True)    def __str__(self):        return self.nameclass User(models.Model):    '''    用户表    '''    name = models.CharField(max_length=32, verbose_name='用户名')    password = models.CharField(max_length=32, verbose_name='密码')    roles = models.ManyToManyField('Role', blank=True, verbose_name='用户拥有的角色')    def __str__(self):        return self.name    class Meta:        verbose_name_plural = '用户'        verbose_name = '用户表'

二级菜单的 数据结构

data = [{    'permissions__url': '/customer/list/',    'permissions__title': '客户列表',    'permissions__menu__title': '信息列表',    'permissions__menu__icon': 'fa-code-fork',    'permissions__menu_id': 1},    {    'permissions__url': '/customer/list/',    'permissions__title': '用户列表',    'permissions__menu__title': '信息列表',    'permissions__menu__icon': 'fa-code-fork',    'permissions__menu_id': 1},{    'permissions__url': '/customer/add/',    'permissions__title': '增加客户',    'permissions__menu__title': None,    'permissions__menu__icon': None,    'permissions__menu_id': None}, {    'permissions__url': '/customer/edit/(\\d+)/',    'permissions__title': '编辑客户',    'permissions__menu__title': None,    'permissions__menu__icon': None,    'permissions__menu_id': None}]"""{  1:{    'title':'信息列表',    'icnon':'fa-code-fork',    'children': [        {'title': '客户列表','url':'/customer/list/ },        {'title': '用户列表','url':'/customer/list/ }    ]  }}"""

流程:

  1. 保存菜单的信息到 session 中
# 在 rbac app中 定义 一个文件 处理 信息的 录入def init_permisson(request, obj):    """    权限信息的初识化    保存权限和菜单的信息    :param request:    :param obj:    :return:    """    ret = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__url',                                                                        'permissions__title',                                                               'permissions__menu__title',                                                                      'permissions__menu__icon',                                                                        'permissions__menu_id',                                                                        ).distinct()    print(ret)    # 存放权限信息    permission_list = []    # 存放菜单信息    menu_dict = {}  VGB M,K.L/;['}.+*6654=-908877                                }0']    for item in ret:        # 将所有的权限信息添加到permission_list        permission_list.append({'url': item['permissions__url']})        # 构造菜单的数据结构        menu_id = item.get('permissions__menu_id')        # 表示当前的权限是不做菜单的权限        if not menu_id:            continue        # 可以做菜单的权限        if menu_id not in menu_dict:            menu_dict[menu_id] = {                'title': item['permissions__menu__title'],  # 一级菜单标题                'icon': item['permissions__menu__icon'],                'children': [{'title': item['permissions__title'], 'url': item['permissions__url']}]            }        else:            menu_dict[menu_id]['children'].append(                {'title': item['permissions__title'], 'url': item['permissions__url']})    print(menu_dict)    # 保存权限信息    request.session[settings.PERMISSION_SESSION_KEY] = permission_list    # 保存菜单信息    request.session[settings.PERMISSION_MENU_KEY] = menu_dict
  1. 定义html代码块 及 inclusion_tag

    html代码块

{% for item in menu_list %}
{
{ item.title }}
{% for child in item.children %}
{
{ child.title }}
{% endfor %}
{% endfor %}

​ inclusion_tag rbac.py

from django import templatefrom django.conf import settingsimport reregister = template.Library()@register.inclusion_tag('rbac/menu.html')def menu(request):    menu_dict = request.session.get(settings.PERMISSION_MENU_KEY)    return {'menu_list': menu_dict.values()}
  1. Css样式 css/menu.css
.multi-menu .item {    background-color: white;}.multi-menu .item > .title {    padding: 10px 5px;    border-bottom: 1px solid #dddddd;    cursor: pointer;    color: #333;    display: block;    background: #efefef;    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));    background: -ms-linear-gradient(bottom, #efefef, #fafafa);    background: -o-linear-gradient(bottom, #efefef, #fafafa);    filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";    box-shadow: inset 0 1px 1px white;}.multi-menu .item > .body {    border-bottom: 1px solid #dddddd;}.multi-menu .item > .body a {    display: block;    padding: 5px 20px;    text-decoration: none;    border-left: 2px solid transparent;    font-size: 13px;}.multi-menu .item > .body a:hover {    border-left: 2px solid #2F72AB;}.multi-menu .item > .body a.active {    border-left: 2px solid #2F72AB;}

使用:

在 母版中  导入  css 样式   以及使用   inclusion_tag  返回菜单列表    
{% load rbac %} {% menu request %}

二级菜单的 点击动画

$(function () {    $('.item .title').click(function () {        {#$(this).next().toggleClass('hide')#}        $('.item .title').siblings($(this)).slideUp(100);         $(this).next().slideDown(100);         {#展开当前 一级菜单 下的 二级菜单#}         {#$(this).next().removeClass('hide');#}         {# 关闭其他菜单 下的 二级菜单#}         {#$(this).parent().siblings().find('.body').addClass('hide');#}    })})

菜单的排序

给一级菜单进行排序

在model 中 添加 权重 字段

# 1.model 中  的权限表 添加 权重字段 weight = models.IntegerField(default=1, verbose_name='权重')# 2.查询出权重 将其加入到 menu_dict 的一级菜单中 # 3. 在  inclusion_tag 中 给菜单进行排序    # 导入 OrderedDict 有序字典   因为字典是无序的  查询出的顺序不一定      from collections import OrderedDict    ordered_dict = OrderedDict()                     # 给菜单进行排序    for i in sorted(menu_dict, key=lambda a: menu_dict[a]['weight'], reverse=True):        # 将  menu_dict  循环添加到 实例化的  OrderedDict() 中        ordered_dict[i] = menu_dict[i]

非菜单权限的归属问题

  • 信息列表 # 一级菜单

    ​ 客户列表 # 二级菜单

    添加客户    #  非菜单权限     编辑客户    #  非菜单权限
  • 财务列表

    缴费列表
  • 权限表中

    menu_id : 关联的菜单

    parent_id: 外键关联自己 三级菜单 ‘self’ 判断从属于那个权限

    id url title menu_id parent_id

    1 /list/ 客户列表 1 null

    2 /add/ 添加客户 null 1

  1. 给权限表中 加入 paren 外键的字段 可以为空

    paren = models.ForeignKey('self', null=True, blank=True)
  2. 获取 paren 关联的 id 也就是 父id 从属于那个权限 以及 本权限的id

    permission = obj.roles.all().filter(permissions__url__isnull=False)    .values('permissions__url',            'permissions__title',                                                                           'permissions__menu__title',                                                                     'permissions__menu__font',            'permissions__menu__weight',  # 权重            'permissions__menu_id',            #'permissions__weight',            'permissions__paren_id',  # 关联的 归属id            'permissions__id',  # 本权限的 id            ).distinct()
  3. 將 id pid 存放到 permissions_list 中的每个字典中

    permissions_list.append({'url': item['permissions__url'],                         'id': item['permissions__id'],                         'pid': item['permissions__paren_id'], })   #paren  括弧
  4. 存放 权限id 到 二级菜单的 children中

    'children': [{'title': item['permissions__title'],                              'url': item['permissions__url'],                              'id': item['permissions__id'],                              }]}
  5. 从 中间件中获取到 两个id 做判断 將 从属的 id 存放到 request 对象中

    # 记录 paren 的 id 到 request 中id, pid = i['id'], i['pid']if pid:    #  有PID表示当前访问的权限是子权限   它有父权限 要让这个父权限展开    request.xxx = pidelse:    # 表示当前访问的权限是父权限  要让自己展开    request.xxx = id
  6. 从 inclusion_tag 中 取到 没个菜单的 children 循环 判断 从属的 id 是不是 本 权限的 id

    给从属的 权限加上 显示  及 active item['class'] = 'hide'        for child in item['children']:            # if re.match("^{}$".format(child['url']), request.path_info):            if request.xxx == child['id']:                child['class'] = 'active'                item['class'] = ''

路径导航

面包屑 导航

注意 :

​ 权限信息放入到session中。进行json序列化

​ 字段的key 如果是数字化,会变成数字字符串

  1. 將 权限 dict 中加入 title 描述

    字典中 本身就有 路径 以及 描述

    permissions_dict[item['permissions__id']] = ({'url': item['permissions__url'],                                             'id': item['permissions__id'],                                             'pid': item['permissions__paren_id'],                                             'title': item['permissions__title']})
  2. 在 中间件中 创建 一个 面包屑的列表 存到 request 中

    # 创建列表   使用 反射  添加到 request 中   名字在 settings 中配置setattr(request, setting.BREADCRUMB, [ {'url': reverse('index'), 'title': '首页'},])# 其他导航路径的添加if pid:    #  有PID表示当前访问的权限是子权限   它有父权限 要让这个父权限展开    request.xxx = pid    # 获取 父 权限的 内容    p_dict = permissions_dict[str(pid)]    # 將父权限的内容 添加到 面包屑列表中    getattr(request,setting.BREADCRUMB).append(        {'url': p_dict['url'], 'title': p_dict['title']}    )    # 添加子 内容 到 列表中    getattr(request,setting.BREADCRUMB).append(        {'url': i['url'], 'title': i['title']}    )else:    # 表示当前访问的权限是父权限  要让自己展开    request.xxx = id    getattr(request,setting.BREADCRUMB).append(        {'url': i['url'], 'title': i['title']}    )
  3. 信创建 inclusion_tag 获取 面包屑列表

    @register.inclusion_tag('rbac/breadcrumb.html')def breadcrumb(request):    breadcrumb_list = getattr(request,setting.BREADCRUMB)    return {'breadcrumb_list': breadcrumb_list}

    HTML 页面 rbac/breadcrumb.html

  4. 在 母版中使用

    {% breadcrumb request %}

    用到反射 (反射复习)

权限控制到按钮级别

同过 name 别名 来判断 路径 將name 存放在 权限中

name = models.CharField(max_length=32, verbose_name='url别名')存放所有 权限的  别名
  1. 获取 自己的url别名 以及

    'permissions__paren__name',  # 关联的 归属  权限 名字         'permissions__name',  # url别名
  2. 用别名做 key 添加 关联字段的 名字

    # 添加所有的 权限 url   使用  url 别名 当做 Keypermissions_dict[item['permissions__name']] = (            {'url': item['permissions__url'],             'id': item['permissions__id'],             'p_name': item['permissions__paren__name'],  # 添加 查询 当前关联的 权限的名字             'pid': item['permissions__paren_id'],         'title': item['permissions__title']})

    在中间件中 获取 p_name 的值

    通过 值 找到 父及菜单的所有内容

    id, pid, p_name = i['id'], i['pid'], i['p_name']p_dict = permissions_dict[p_name]   查找 父及菜单内容
  3. 创建 filter 过滤器 反回 T or F 来判断 是否显示 标签

    @register.filter()def has_permission(request, name):    # 判断name是否在权限的字典中    if name in request.session.get(settings.PERMISSION_SESSION_KEY):        return True
  4. 在母版中 使用

    {% if request|has_permission:'customer_edit' and request|has_permission:'customer_del' %} {% if request|has_permission:'customer_del' %}

区分 一二级联动 菜单

  1. 获取所有的 一级 菜单 一级 权限 信息 做展示

  2. 修改 权限 信息的 数据结构 区分 二三级 菜单 循环进行展示

# 显示 一级菜单 联动 二及菜单def menu_list(request):    menu_obj = models.Menu.objects.all()    # 获取 菜单的 id    mid = request.GET.get('mid')    if mid:        # 如果有 条件 则对数据进行筛选        permission_all = models.Permission.objects.filter(Q(menu_id=mid) | Q(paren__menu_id=mid))    else:        permission_all = models.Permission.objects.all()# 实例化 有序字典  修改 数据结构  將 数据分为  二三级菜单 存入 有序字典中    permission_dict = OrderedDict()    for item in permission_query_dict:        # 判断 二级菜单        if item.get('menu_id'):            permission_dict[item['id']] = item            item['children'] = []    for item in permission_query_dict:        # 判断三级菜单        pid = item.get('paren_id')        if pid:            permission_dict[pid]['children'].append(item)                print(permission_dict)

html

{% extends 'layout.html' %}{% block css %}    {% endblock %}{% block content %}    
菜单管理
新建
{% for field in menu_obj %} {# field.pk|safe 将数字转义为字符串 #}
{% endfor %}
名称 图标 操作
{ { field.title }}
权限管理
批量操作
新建
{% for p_permission in permission_dict %}{# 二级菜单的 展示 #}
{% for c_permission in p_permission.children %}三级菜单的展示
{% endfor %} {% endfor %}
描述 URR URR别名 操作
{ { p_permission.title }} { { p_permission.url }} { { p_permission.name }}
{ { c_permission.title }} { { c_permission.url }} { { c_permission.name }}
{% endblock %}{% block js %} {% endblock %}

应用rbac权限组件

  1. 有一个要应用的项目

  2. 把rbac的app拷贝到新项目中,注册

  3. 生成rbac相关的表

    1. 删除rbac/migrations下的除init之外的py文件
    2. 执行数据库迁移的命令
  4. 使用admin录入权限信息

    1. 创建超级用户
    2. 登录admin录入权限信息
      1. 权限信息 url地址 不带^$
      2. 角色 给角色分配权限
      3. 用户 给用户分配角色
  5. 应用登录后权限信息的初始化

    from rbac.service.permission import init_permissonfrom rbac.models import User# 登录成功后init_permisson(request,obj)
  6. 使用权限的中间件

MIDDLEWARE = [    ...    'rbac.middlewares.rbac.RbacMiddleware']

​ 在settings中进行配置

# ################################ 权限的配置 ################################# 权限的keyPERMISSION_SESSION_KEY = 'permissions'# 菜单的keyPERMISSION_MENU_KEY = 'menus'WHITE_LIST = [    r'^/login/$',    r'^/reg/$',    r'^/admin/.*',]

7.应用动态生成一级菜单

  1. 使用menu 的inclusion_tag
  2. 应用css样式
{% load rbac %} {% menu request %}

2.动态生成二级菜单

信息列表 - 一级菜单

​ 客户列表 - 二级菜单

财务列表

​ 缴费列表

icon 图标库 爬虫

#!/usr/bin/env python# -*- coding:utf-8 -*-from django.utils.safestring import mark_safeimport requestsfrom bs4 import BeautifulSoupresponse = requests.get(    url='http://fontawesome.dashgame.com/',)response.encoding = 'utf-8'soup = BeautifulSoup(response.text, 'html.parser')web = soup.find(attrs={'id': 'web-application'})icon_list = []for item in web.find_all(attrs={'class': 'fa-hover'}):    tag = item.find('i')    class_name = tag.get('class')[1]    icon_list.append([class_name, str(tag)])print(icon_list)

应用权限组件

  1. 拷贝rbac组件到新的项目中,注册app
  2. 修改用户表,继承rbac中的User
class User(models.Model):    """    用户表    """    # name = models.CharField(max_length=32, verbose_name='名称')    # password = models.CharField(max_length=32, verbose_name='密码')    roles = models.ManyToManyField(Role, verbose_name='用户拥有的角色', blank=True)    # def __str__(self):    #     return self.name    class Meta:        abstract = True  # 数据库迁移时候不会生成表,用来做基类class UserProfile(User, models.Model):
  1. 执行数据库迁移的命令
    1. 删除rbac下migrations中的记录
    2. 注释掉admin中User表
    3. roles = models.ManyToManyField(Role, verbose_name='用户拥有的角色', blank=True) # 关联的字段不要写成字符串形式
  2. 设置rbac的url
url(r'rbac/', include('rbac.urls',namespace='rbac'))
  1. 菜单管理

  2. 权限的录入

    1. 所有的url要头name
    2. 不要忽略rbac namespace
    3. 注意url和别名的长度
    4. 构建层级结构
  3. 角色管理

  4. 分配权限

    1. 注意用新的用户表替换rbac中的User
    2. 给不同角色分配权限
    3. 给不同用户分配角色
  5. 应用上权限

    1. 应用中间件 在settings中写上权限的配置
    # 权限的keyPERMISSION_SESSION_KEY = 'permissions'# 菜单的keyPERMISSION_MENU_KEY = 'menus'WHITE_LIST = [    r'^/login/$',    r'^/reg/$',    r'^/admin/.*',]NO_PERMISSION_LIST = [    r'^/index/$',    r'^/logout/$',]# 路径导航BREADCRUMB = 'breadcrumb_list'# 路径导航CURRENT_MENU = 'current_parent_id'
    1. 登录成功后权限信息的初识化
    from rbac.service.permission import init_permisson# 权限信息的初始化init_permisson(request,obj)
  6. 动态生成二级菜单

    1. 在layout中使用
```导入CSS js {% load rbac %}{% menu request %}```
  1. 应用路径导航

    {% breadcrumb request %}
  2. 权限控制到按钮级别

{% load rbac %}{% if request|has_permission:"consult_add" %}    添加{% endif %}

权限如何能不重新登录,就应用新的权限?

  • 用户表加字段 存 session_key

  • 通过session_key 拿到用户的session数据 更新权限

    from django.contrib.sessions.models import Sessionfrom django.contrib.sessions.backends.db import SessionStoredecode   encode

权限如何控制到行级别?

加条件表

转载于:https://www.cnblogs.com/zhang-zi-yi/p/10800426.html

你可能感兴趣的文章
每次要主板放电后才能正常开机
查看>>
Zabbix添加自定义监控项
查看>>
uboot-2010.06移植到mini2440经验(2)配置时钟
查看>>
八十年代的古董级晶体管直流稳压电源 WYJ-15V/1A
查看>>
authentication password与scheme区别
查看>>
我的友情链接
查看>>
[Zephir官方文档翻译之五] 入门指导
查看>>
【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇...
查看>>
linux alias
查看>>
WORDPRESS巧用插件实现历史记录栏
查看>>
命令-gzip/gunzip/zcat
查看>>
我的友情链接
查看>>
2012-2-7
查看>>
The type XXX cannot be resolved 解决方法
查看>>
C#也能PS图片,还能为网站Ajax上传图片同时生成微缩图(附Demo)
查看>>
山的那边是什么?写在H3CSE考后
查看>>
标注添加信息窗口
查看>>
XenApp
查看>>
system sys,sysoper sysdba 的区别
查看>>
将数据导入数据库
查看>>